// This file contains the class CaptureRenderAdapter. The class connects a
// VideoCapturer to any number of VideoRenders such that the former feeds the
// latter.
// CaptureRenderAdapter is Thread-unsafe. This means that none of its APIs may
// be called concurrently.

#ifndef MEDIA_BASE_CAPTURERENDERADAPTER_H_
#define MEDIA_BASE_CAPTURERENDERADAPTER_H_

#include <vector>

#include "base/criticalsection.h"
#include "base/sigslot.h"
#include "media/videocapturer.h"

namespace cricket {

	class VideoCapturer;
	class VideoProcessor;
	class VideoRenderer;

	class CaptureRenderAdapter : public sigslot::has_slots<> {
	public:
		static CaptureRenderAdapter* Create(VideoCapturer* video_capturer);
		~CaptureRenderAdapter();

		bool AddRenderer(VideoRenderer* video_renderer);
		bool RemoveRenderer(VideoRenderer* video_renderer);

		VideoCapturer* video_capturer() { return video_capturer_; }
	private:
		struct VideoRendererInfo {
			explicit VideoRendererInfo(VideoRenderer* r)
				: renderer(r),
				render_width(0),
				render_height(0) {
			}
			VideoRenderer* renderer;
			size_t render_width;
			size_t render_height;
		};

		// Just pointers since ownership is not handed over to this class.
		typedef std::vector<VideoRendererInfo> VideoRenderers;

		explicit CaptureRenderAdapter(VideoCapturer* video_capturer);
		void Init();

		// Callback for frames received from the capturer.
		void OnVideoFrame(VideoCapturer* capturer, const VideoFrame* video_frame);

		void MaybeSetRenderingSize(const VideoFrame* frame);

		bool IsRendererRegistered(const VideoRenderer& video_renderer) const;

		VideoRenderers video_renderers_;
		VideoCapturer* video_capturer_;
		// Critical section synchronizing the capture thread.
		mutable base::CriticalSection capture_crit_;
	};

}  // namespace cricket

#endif  // MEDIA_BASE_CAPTURERENDERADAPTER_H_
